package com.zzedu.framework.filer;

import com.zzedu.common.config.RuntimeConfig;
import com.zzedu.common.core.domain.entity.SysUser;
import com.zzedu.common.enums.OnlineStatus;
import com.zzedu.common.utils.AddressUtils;
import com.zzedu.common.utils.IpUtils;
import com.zzedu.common.utils.security.LoginUser;
import com.zzedu.system.domain.SysUserOnline;
import com.zzedu.system.service.ISysUserOnlineService;
import eu.bitwalker.useragentutils.UserAgent;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.session.Session;
import org.springframework.session.data.redis.RedisSessionRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.Executor;

@Component
public class SessionDataSynFilter extends OncePerRequestFilter {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private ISysUserOnlineService sysUserOnlineService;
    @Autowired
    private RedisSessionRepository redisIndexedSessionRepository;
    @Autowired
    private RuntimeConfig runtimeConfig;

    @Resource(name = "busSystemExecutor")
    private Executor executor;
    @Value("${server.port}")
    private Integer port;

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            //记录日志
            if (runtimeConfig.isApiFlag()) {
                reqLog((HttpServletRequest) request);
            }
            //异常了也不影响
            synDb((HttpServletRequest) request);
        } catch (Exception e) {

        }
        filterChain.doFilter(request, response);
    }

    private void reqLog(HttpServletRequest request) {
//        String userAgent = "";
//        ShopReqLog shopReqLog = new ShopReqLog();
//        try {
//            // 接收到请求，记录请求内容
//            String openId = "no";
//            SysUser currentUser = LoginUserUtils.getSysUser();
//            if (currentUser != null) {
//                openId = LoginUserUtils.getLoginName();
//            }
//            shopReqLog.setReqIp(IpUtils.getIpAddr(request));
//            shopReqLog.setReqTime(LocalDateTime.now());
//            shopReqLog.setOpenId(openId);
//            shopReqLog.setHost(IpUtils.getLocalIpAddress());
//            shopReqLog.setPort(port);
//            shopReqLog.setReqUrl(request.getRequestURI());
//            shopReqLog.setUserAgent(request.getHeader("User-Agent"));
//            userAgent = shopReqLog.getUserAgent();
//            if (!"clb-healthcheck".equalsIgnoreCase(userAgent)) {
//                Map<String, String> header = Maps.newHashMap();
//                Enumeration<String> enumeration = request.getHeaderNames();
//                if (null != enumeration) {
//                    while (enumeration.hasMoreElements()) {
//                        String key = enumeration.nextElement();
//                        header.put(key, request.getHeader(key));
//                    }
//                }
//                shopReqLog.setHeader(JSON.toJSONString(header));
//                shopReqLog.setGmtCreate(LocalDateTime.now());
//                String ust = userAgent.toLowerCase();
//                boolean isBankAppReq = ust.contains("bankabc");
//                shopReqLog.setNormal(isBankAppReq ? 0 : 1);
//                CompletableFuture.runAsync(() -> {
//                    try {
//                        String location = AddressUtils.getRealAddressByIPRealTime(shopReqLog.getReqIp());
//                        shopReqLog.setLocation(location);
//                    } catch (Exception e) {
//                        logger.error("解析IP对应坐标出错,详细:", e.getMessage());
//                    }
//                    shopReqLogMapper.insert(shopReqLog);
//
//                }, executor);
//
//            }
//        } catch (Exception e) {
//            logger.error("ClientValidAspect写入日志异常,详细:{}", e.getMessage());
//        }
    }

    /**
     * 同步session 数据到 db
     *
     * @param request
     */
    private void synDb(HttpServletRequest request) {
        if (null != request.getSession(false)) {
            Session session = redisIndexedSessionRepository.findById(request.getRequestedSessionId());
            if (null == session) {
                return;
            }
            SecurityContext securityContext = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
            if (null == securityContext) {
                return;
            }
            Authentication auth = securityContext.getAuthentication();
            if (null == auth) {
                return;
            }
            Object object = auth.getPrincipal();
            if (null == object || !(object instanceof LoginUser)) {
                return;
            }
            LoginUser userSecurity = (LoginUser) object;
            if (null == userSecurity || null == userSecurity.getUser()) {
                return;
            }
            SysUser loginUser = userSecurity.getUser();
            if (null == loginUser) {
                return;
            }
            SysUserOnline sysUserOnline = new SysUserOnline();
            sysUserOnline.setStartTimestamp(Date.from(session.getCreationTime()));
            sysUserOnline.setLastAccessTime(Date.from(session.getLastAccessedTime()));
            sysUserOnline.setSessionId(session.getId());
            UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
            // 获取客户端操作系统
            String os = userAgent.getOperatingSystem().getName();
            // 获取客户端浏览器
            String browser = userAgent.getBrowser().getName();
            sysUserOnline.setIpaddr(IpUtils.getIpAddr(request));
            sysUserOnline.setBrowser(browser);
            sysUserOnline.setOs(os);
            sysUserOnline.setLoginLocation(AddressUtils.getRealAddressByIP(sysUserOnline.getIpaddr()));
            sysUserOnline.setLoginName(loginUser.getUserName());
            if (null != loginUser.getDept()) {
                sysUserOnline.setDeptName(loginUser.getDept().getDeptName());
            }
            sysUserOnline.setStatus(OnlineStatus.on_line.name());
            sysUserOnline.setUserId(loginUser.getId());
            sysUserOnline.setExpireTime(Date.from(session.getLastAccessedTime().plus(session.getMaxInactiveInterval())));
            sysUserOnlineService.saveOnline(sysUserOnline);
        }
    }
}
